<template>
  <AppMainAutoWidth :width="$attrs.width">
    <div class="ies-table"
         ref="IesTable">
      <el-table v-bind="$attrs"
                :summary-method="summaryMethod"
                :span-method="spanMethod"
                :ref="$attrs.ref?$attrs.ref:'multipleTable'"
                tooltip-effect="dark"
                :header-cell-style="{background: '#f6f6f6'}"
                @selection-change="selectionThead.length>0?handleSelectionChange($event):null"
                @select="selectionThead.length>0?handleSelection($event):null"
                @select-all="selectionThead.length>0?handleSelectionAll($event):null"
                @row-click="handleRowClick"
                :row-class-name="tableRowClassName"
                :data="iesTableData"
                :height="tableHeight"
                :max-height="maxTableHeightVal"
                :style="{width:$attrs.width}"
                v-loading="$attrs.loading?$attrs.loading:false"
                border>
        <el-table-column v-if="selectionThead.length>0&&$attrs.tableType!=='expand' && selectionThead[0].isShow !== false"
                         type="selection"
                         :align="selectionThead[0].align?selectionThead[0].align:''"
                         :width="selectionThead[0].width?selectionThead[0].width:'55px'"
                         :fixed="selectionThead[0].fixed!==undefined?selectionThead[0].fixed:true"
                         :selectable="checkSelect"></el-table-column>
        <el-table-column v-if="indexThead.length>0"
                         type="index"
                         :align="indexThead[0].align?indexThead[0].align:''"
                         :width="indexThead[0].width?indexThead[0].width:'55px'"
                         :label="indexThead[0].label?labelName(indexThead[0].label):null"
                         :fixed="indexThead[0].fixed!==undefined?indexThead[0].fixed:true"
                         :index="tableIndexMethod"></el-table-column>

        <template v-for="item in theadFieldsData">
          <el-table-column v-if="item.isShow !== false"
                           :key="item.prop"
                           :prop="item.prop"
                           :align="item.align?item.align:''"
                           :label="item.label? labelName(item.label):null"
                           :title="item.label? labelName(item.label):null"
                           :fixed="item.fixed!==undefined?item.fixed:null"
                           :width="item.width?item.width:'auto'"
                           :style="{minWidth:!item.width?'200px':'auto'}"
                           :show-overflow-tooltip="item.showTooltip!==undefined?item.showTooltip:true">
            <template slot-scope="scope">
              <div v-if="item.type==='code'">{{item.options&&item.options!=='{}'?$t(item.options[scope.row[item.prop]]):$t('message.iesTable.codeTips')}}</div>
              <div class="flex justify-center align-center"
                   v-else-if="item.prop==='operation'">
                <!-- -------------------------C 查看------------------------------------------- -->
                <el-button v-if="item.options.readonly && !(item.options.hiddenInfo && item.options.hiddenInfo.readonly && scope.row[item.options.hiddenInfo.readonly.prop] === item.options.hiddenInfo.readonly.value)"
                           @click="readonly(scope.row)"
                           size="mini"
                           :style="{ color: item.options.disabledInfo && item.options.disabledInfo.readonly && scope.row[item.options.disabledInfo.readonly.prop] && scope.row[item.options.disabledInfo.readonly.prop] === item.options.disabledInfo.readonly.value ? '' : '#409EFF' }"
                           :disabled="item.options.disabledInfo && item.options.disabledInfo.readonly && scope.row[item.options.disabledInfo.readonly.prop] && scope.row[item.options.disabledInfo.readonly.prop] === item.options.disabledInfo.readonly.value"
                           :title="item.title!==undefined&&item.title.readonly!==undefined?item.title.readonly:$t('i18n_readonly')">
                  <i class="el-icon-view"></i>
                </el-button>
                <el-button v-if="item.options.add && (item.hiddenInfo!==undefined && item.hiddenInfo.add!==undefined?(scope.row[item.hiddenInfo.add.prop] === item.hiddenInfo.add.value):true)"
                           @click="add(scope.row)"
                           size="mini"
                           style="color:#409EFF;"
                           :title="item.title!==undefined&&item.title.add!==undefined?item.title.add:$t('i18n_readonly')">
                  <i class="el-icon-plus"></i>
                </el-button>
                <el-button v-if="item.options.minus?item.options.minus:false"
                           @click="minus(scope.row)"
                           size="mini"
                           style="color:#409EFF;"
                           :title="item.title!==undefined&&item.title.minus!==undefined?item.title.minus:$t('i18n_minus')">
                  <i class="el-icon-minus"></i>
                </el-button>
                <el-button v-if="item.options.edit && !(item.options.hiddenInfo && item.options.hiddenInfo.edit && scope.row[item.options.hiddenInfo.edit.prop] === item.options.hiddenInfo.edit.value)"
                           @click="edit(scope.row)"
                           size="mini"
                           :style="{ color: item.options.disabledInfo && item.options.disabledInfo.edit && scope.row[item.options.disabledInfo.edit.prop] && scope.row[item.options.disabledInfo.edit.prop] === item.options.disabledInfo.edit.value ? '' : '#409EFF' }"
                           :disabled="item.options.disabledInfo && item.options.disabledInfo.edit && scope.row[item.options.disabledInfo.edit.prop] && scope.row[item.options.disabledInfo.edit.prop] === item.options.disabledInfo.edit.value"
                           :title="item.title!==undefined&&item.title.edit!==undefined?item.title.edit:$t('i18n_edit')">
                  <i class="el-icon-edit"></i>
                </el-button>
                <el-button v-if="item.options.editOther"
                           @click="editOther(scope.row)"
                           size="mini"
                           style="color:#409EFF;"
                           :title="item.title!==undefined&&item.title.editOther!==undefined?item.title.editOther:$t('i18n_edit')">
                  <!-- <i class="el-icon-edit"></i> -->
                  <i class="el-icon-edit-outline"></i>
                </el-button>

                <!-- -------------------------------------------------------------------- -->
                <el-button v-if="item.options.delete && !(item.options.hiddenInfo && item.options.hiddenInfo.delete && scope.row[item.options.hiddenInfo.delete.prop] === item.options.hiddenInfo.delete.value)"
                           @click="del(scope.row)"
                           size="mini"
                           style="color:red;"
                           :title="item.title!==undefined&&item.title.delete!==undefined?item.title.delete:$t('i18n_delete')">
                  <i class="el-icon-delete-solid"></i>
                </el-button>
                <el-button v-if="item.options.delt"
                           @click="delt(scope.row)"
                           size="mini"
                           style="color:red;"
                           :title="item.title!==undefined&&item.title.delt!==undefined?item.title.delt:$t('i18n_delete')">
                  <i class="el-icon-remove-outline"></i>
                </el-button>
                <el-button v-if="item.options.location"
                           @click="location(scope.row)"
                           size="mini"
                           style="color:#409EFF;font-size:14px"
                           :title="item.title!==undefined&&item.title.location!==undefined?item.title.location:$t('i18n_delete')">
                  <i class="el-icon-location"></i>
                </el-button>
                <el-switch v-if="item.options.change && !(item.options.hiddenInfo && item.options.hiddenInfo.change && scope.row[item.options.hiddenInfo.change.prop] === item.options.hiddenInfo.change.value)"
                           :disabled="item.options.disabledInfo && item.options.disabledInfo.change && scope.row[item.options.disabledInfo.change.prop] && scope.row[item.options.disabledInfo.change.prop] === item.options.disabledInfo.change.value"
                           :value="scope.row.isActive"
                           @change="change(scope.row)"
                           style="margin-left:10px;"></el-switch>
                <el-button :type="item.options.type"
                           v-if="item.options.export"
                           @click="exportExl(scope.row)"
                           style="margin-left:10px;; font-size: 16px; font-weight: bold">
                  <i class="el-icon-download"></i>
                </el-button>
                <el-upload v-if="item.options.upload"
                           ref="upload"
                           :action="actionUrl"
                           :show-file-list="false"
                           auto-upload
                           :data="{id: scope.row.id}"
                           :headers="{
                    Authorization: `Bearer ${token}`
                  }"
                           accept=".xls, .xlsx"
                           :on-success="handleSuccess"
                           :on-error="handleError"
                           :before-upload="beforUpload">
                  <el-button :type="item.options.type"
                             style="margin-left: 10px; font-size: 16px; font-weight: bold">
                    <i class="el-icon-upload2"></i>
                  </el-button>
                </el-upload>
              </div>

              <span v-else>{{scope.row[item.prop]}}</span>
            </template>
          </el-table-column>
        </template>
      </el-table>
      <slot name="footer" />
      <div v-if="pagination"
           class="pagination-ground">
        <p class="pagination-page">
          <span class="margin-right">{{$t('pagination.total')}} {{paginationOptions.total}} {{$t('pagination.record')}}</span>
          <span>{{$t('pagination.number')}} {{paginationOptions.current}}/{{paginationOptions.count}} {{$t('pagination.page')}}</span>
        </p>
        <el-pagination background
                       @size-change="handleSizeChange"
                       @current-change="handleCurrentChange"
                       :current-page="paginationOptions.current"
                       :page-count="paginationOptions.count"
                       :page-sizes="paginationOptions.sizes"
                       :page-size="paginationOptions.size"
                       :layout="paginationOptions.layout?paginationOptions.layout:'prev,pager,next,sizes,jumper'"
                       :total="paginationOptions.total"
                       small></el-pagination>
      </div>
    </div>
  </AppMainAutoWidth>
</template>

<script>
import { mapGetters } from 'vuex'
import { vueScrollSetting } from '@config/vue-scroll-setting'
export default {
  name: 'IesTable',
  props: {
    tableIndexMethod: { //
      type: Function
    },
    summaryMethod: {
      type: Function
    },
    spanMethod: {
      type: Function
    },
    actionUrl: {
      type: String,
      default: '/'
    },
    tableData: {
      type: Array,
      default: () => {
        return []
      }
    },
    theadData: {
      type: Array,
      default: () => {
        return []
      }
    },
    paginationOptions: {
      type: Object,
      default: () => {
        return {
          current: 1, // 当前页
          count: 0, // 总页数后台返回的字段是pages
          size: 10, // 每页多少条
          total: 0, // 共多少条
          sizes: [10, 20, 30, 40]// 每页多少条
        }
      }
    },
    pagination: {
      type: Boolean,
      default: true
    },
    editPassOperate: {
      type: Boolean,
      default: false
    },
    delPassOperate: {
      type: Boolean,
      default: false
    },
    showConfirm: {
      type: Boolean,
      default: false
    },

    height: {
      type: String,
      default: 'auto'
    },
    maxTableHeight: {
      type: String,
      default: 'auto'
    },
    selectType: {
      type: String,
      default: 'multiple'
    },
    selectIdName: { // 要回填的选择id
      type: String,
      default: 'id'
    },
    autoFixed: { // 自动适应置顶屏幕
      type: Boolean,
      default: false
    },
    checkSelectObj: { // 要回填的选择id
      type: Object,
      default() {
        return {
          keyName: 'id',
          keyVal: ''
        }
      }
    },
    selectOptions: { // 已选数据
      type: Array,
      default: () => {
        return []
      }
    }
  },
  data() {
    return {
      uploadLoading: null,
      scrollPanel: vueScrollSetting,
      top: '',
      screenHeight: document.documentElement.clientHeight, // 屏幕高度
      tableHeight: this.height,
      iesTable: null,
      iesWidth: ''
    }
  },
  watch: {
    screenHeight(newValue, oldValue) {
      if (this.height === 'auto') {
        if (this.top < this.getViewPortHeight() / 2) { // table的top在半屏幕之下时
          this.tableHeight = this.tableHeightChange(newValue)
        } else {
          if (this.messageTips) {
            this.tableHeight = `calc(${this.getViewPortHeight()}px - 230px)`
          } else {
            this.tableHeight = `calc(${this.getViewPortHeight()}px - 190px)`
          }
        }
      }
    },
    opened(newValue, oldValue) {
      this.iesWidth = this.appMainWidth - 80
      this.$nextTick(() => {
        this.iesTable = this.$refs.IesTable.getBoundingClientRect()
        this.top = this.iesTable.top
        this.screenHeight = document.documentElement.clientHeight // 窗口高度
      })
    },
    tableData(newValue, oldValue) {
      this.setSelectState()
    },
    messageTips(newValue, oldValue) {
      this.tableChange()
    }

  },
  computed: {
    ...mapGetters([
      'token',
      'appMainWidth'
    ]),
    opened() {
      const opened = this.$store.state.app.sidebar.opened
      return opened
    },
    indexThead() { // 序号列
      return this.theadData.filter((item) => {
        return item.prop === 'index'
      })
    },
    selectionThead() { // 选择列
      return this.theadData.filter((item) => {
        return item.prop === 'selection'
      })
    },
    theadFieldsData() { // 字段列
      const fieldsData = this.theadData.filter((item) => {
        return item.prop !== 'selection' && item.prop !== 'index'
      })
      return (this.indexThead.length > 0 || this.selectionThead.length > 0) ? fieldsData : this.theadData
    },
    expandWidth() {
      return `calc(100vw - ${this.opened ? '300px' : '120px'})`
    },
    iesTableData() {
      this.$nextTick(() => {
        this.$refs[this.$attrs.ref || 'multipleTable'].doLayout()
      })
      return this.tableData
    },
    maxTableHeightVal() { // 流体最大高度
      return this.maxTableHeight === 'auto' ? this.tableHeight : this.maxTableHeight
    },
    messageTips() {
      return Boolean(this.$store.state.settings.messageTips)
    }
  },
  created() {
    this.$nextTick(() => {
      this.iesTable = this.$refs.IesTable.getBoundingClientRect()
      this.top = this.iesTable.top
      this.screenHeight = document.documentElement.clientHeight // 窗口高度
      this.tableChange()
    })
  },
  mounted() {
    window.addEventListener('resize', this.onresize)
  },
  updated() {
    this.$nextTick(() => {
      this.$refs[this.$attrs.ref || 'multipleTable'].doLayout()
    })
  },
  methods: {
    tableChange() {
      if (this.height === 'auto') {
        if (this.top < this.getViewPortHeight() / 2) { // table的top在半屏幕之下时
          this.tableHeight = this.tableHeightChange(this.screenHeight)
        } else {
          if (this.messageTips) {
            this.tableHeight = `calc(${this.getViewPortHeight()}px - 230px)`
          } else {
            this.tableHeight = `calc(${this.getViewPortHeight()}px - 190px)`
          }
        }
      } else {
        this.tableHeight = this.height
      }
    },
    onresize() {
      this.top = this.iesTable.top // table top
      this.screenHeight = document.documentElement.clientHeight // 窗口高度
      this.iesWidth = this.appMainWidth - 80
      this.tableChange()
    },
    getViewPortHeight() { // 获取可视区高度
      return document.documentElement.clientHeight || document.body.clientHeight
    },
    getScrollTop() { // 获取滚动条垂直位置
      return document.documentElement.scrollTop || document.body.scrollTop
    },
    clearSelection() {
      this.$refs.multipleTable.clearSelection()
    },
    handleRowClick(row) {
      this.$emit('row-click', row)
    },
    checkSelect(row, index) {
      let isChecked = true
      if (row[this.checkSelectObj.keyName] && row[this.checkSelectObj.keyName] === this.checkSelectObj.keyVal) { // 判断里面是否存在某个参数
        isChecked = false
      } else {
        isChecked = true
      }

      return isChecked
    },
    getFirstData(thead, data) {
      let text = ''
      let value = ''
      thead.map((item) => {
        if (data !== undefined && data.length > 0) {
          data.map((item1, key1, ary) => {
            if (item.type === 'code') {
              text = item.options[ary[0][item.name]]
            } else {
              value = item1[item.name]
            }
          })
        }
      })

      return (text + ':' + value)
    },
    moreDetail(item, row) {
      if (item.popover.tableName !== undefined && row[item.popover.tableName] !== undefined) {
        this.$set(item.popover, 'tableData', row[item.popover.tableName])
      }
    },
    tableHeightChange(screenHeight) {
      const height = this.messageTips ? 150 : 88

      return screenHeight - this.top - height + 'px'
    },
    labelName(data) { // 多语言切换
      if (data.indexOf('.') !== -1) {
        return this.$t(data)
      } else if (data.indexOf('i18n') !== -1) {
        return this.$utils.getLabelName(data, this)
      } else {
        return data
      }
    },
    handleSelectionChange(data) {
      let selectOptions = data

      if (this.selectType === 'single') {
        selectOptions = data.length > 0 ? [data[data.length - 1]] : []
      }
      this.$emit('tableSelectionChange', selectOptions)
    },
    setSelectState() {
      const self = this
      if (this.selectOptions.length > 0) {
        this.selectOptions.forEach(element => {
          this.tableData.forEach((item) => {
            if (item[this.selectIdName] === element[this.selectIdName]) {
              self.$nextTick(() => {
                self.$refs.multipleTable.toggleRowSelection(item, true)
              })
            }
          })
        })
      }
    },
    handleSelection(selection, row) {
      if (this.selectType === 'single') {
        if (selection.length > 0) {
          selection.forEach((row, key) => {
            if (key < selection.length - 1) {
              this.$refs.multipleTable.toggleRowSelection(row)
              this.$emit('tableSelectionChange', [selection[selection.length - 1]])
            }
          })
        }
      }
      this.$emit('tableSelection', selection)
    },
    handleSelectionAll(selection) {
      if (this.selectType === 'single') {
        this.$message({
          message: '当前状态是单选',
          type: 'warning'
        })
        this.clearSelection()
        this.$emit('tableSelectionChange', [])
      } else {
        this.$emit('tableSelectionChange', selection)
      }
      this.$emit('tableSelection', selection)
    },
    handleSizeChange(data) {
      this.$emit('tableSizeChange', data)
    },
    handleCurrentChange(data) {
      this.$emit('tableCurrentChange', data)
    },
    edit(item) {
      if (this.editPassOperate) {
        this.$emit('edit', item)
      } else {
        if (item.isActive !== undefined && item.isActive) {
          this.$message({
            message: '当前是启用状态，不能进行该操作！',
            type: 'warning'
          })
        } else {
          this.$emit('edit', item)
        }
      }
    },
    editOther(item) {
      if (this.editPassOperate) {
        this.$emit('editOther', item)
      } else {
        if (item.isActive !== undefined && item.isActive) {
          this.$message({
            message: '当前是启用状态，不能进行该操作！',
            type: 'warning'
          })
        } else {
          this.$emit('editOther', item)
        }
      }
    },
    editTime(item) { // 修改失效时间
      this.$emit('editTime', item)
    },
    BindingSurcharge(item) { // 绑定额外费用
      this.$emit('BindingSurcharge', item)
    },
    user(item) { // 绑定额外费用
      this.$emit('user', item)
    },
    readonly(item) { // 查看
      this.$emit('readonly', item)
    },
    location(item) { // 查看
      this.$emit('location', item)
    },
    exportExl(item) {
      this.$emit('exportExl', item)
    },
    del(item) {
      if (this.delPassOperate) {
        this.$emit('del', item)
      } else {
        if (item.isActive !== undefined && item.isActive) {
          this.$message({
            message: '当前是启用状态，不能进行该操作！',
            type: 'warning'
          })
        } else {
          this.$emit('del', item)
        }
      }
    },
    delt(item) {
      if (this.delPassOperate) {
        this.$emit('delt', item)
      } else {
        if (item.isActive !== undefined && item.isActive) {
          this.$message({
            message: '当前是启用状态，不能进行该操作！',
            type: 'warning'
          })
        } else {
          this.$emit('del', item)
        }
      }
    },
    change(item, type) {
      if (this.showConfirm) {
        this.$confirm('此操作将改变当前数据的生效状态, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.$emit('change', Object.assign({ ...item, isActive: type !== undefined && type === 'expand' ? item.isActive : !item.isActive }))
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消操作'
          })
        })
      } else {
        this.$emit('change', Object.assign({ ...item, isActive: type !== undefined && type === 'expand' ? item.isActive : !item.isActive }))
      }
    },
    beforUpload() {
      this.uploadLoading = this.$loading()
    },
    handleSuccess(res, file, fileList) {
      this.uploadLoading.close()
      if (res.code !== 200) {
        this.$message.error(res.message)
      } else {
        this.$message.success('导入成功!')
      }
    },
    handleError() {
      this.uploadLoading.close()
      this.$message.error('导入失败!')
    },
    add(item) {
      this.$emit('add', item)
    },
    minus(item) {
      this.$emit('minus', item)
    },
    tableRowClassName({ row, rowIndex }) {
      if (row.orderStatus === 'OS_CACEL') {
        return 'cancle-row'
      }
      if (row.coverageFlag === 'Y') {
        return 'success-row'
      }
    }


  }
}
</script>

<style scoped lang="scss">
.pagination-ground {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 20px;
}
.el-table {
  &/deep/ .el-table__row {
    &.success-row {
      color: #fdc524;
    }
    &.cancle-row {
      background-color: #e7eaf5;
    }
  }
  &/deep/ .el-table__body {
    .el-table__expanded-cell {
      padding-right: 20px;
    }
    .expand-table-child {
    }
  }
}
</style>
